package com.infoservice.dms.chana.actions;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.infodms.dms.common.Constant;
import com.infodms.dms.common.Utility;
import com.infodms.dms.dao.repair.RepairOrderDao;
import com.infodms.dms.po.TmColorPO;
import com.infodms.dms.po.TmCompanyPO;
import com.infodms.dms.po.TmVehiclePO;
import com.infodms.dms.po.TtAsRepairOrderPO;
import com.infodms.dms.po.TtAsRoAddItemPO;
import com.infodms.dms.po.TtAsRoLabourPO;
import com.infodms.dms.po.TtAsRoManagePO;
import com.infodms.dms.po.TtAsRoRepairPartPO;
import com.infodms.dms.po.TtAsWrQamaintainPO;
import com.infodms.dms.util.sequenceUitl.SequenceManager;
import com.infoservice.de.DEMessage;
import com.infoservice.de.convertor.f2.XmlConvertor4YiQiP01;
import com.infoservice.dms.chana.common.DEConstant;
import com.infoservice.dms.chana.common.RpcException;
import com.infoservice.dms.chana.dao.DeCommonDao;
import com.infoservice.dms.chana.vo.BaseVO;
import com.infoservice.dms.chana.vo.RepairOrderVO;
import com.infoservice.dms.chana.vo.RoAddItemVO;
import com.infoservice.dms.chana.vo.RoLabourVO;
import com.infoservice.dms.chana.vo.RoManageVO;
import com.infoservice.dms.chana.vo.RoRepairPartVO;
import com.infoservice.po3.bean.PO;
import com.infoservice.po3.core.context.DBService;
import com.infoservice.po3.core.context.POContext;
import com.infoservice.po3.core.util.ContextUtil;
import com.infodms.dms.dao.claim.dealerClaimMng.ClaimBillMaintainDAO;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.log4j.Logger;

public class ORC53 extends AbstractReceiveAction {

	private static final Logger logger = Logger.getLogger(ORC53.class);

	private RepairOrderDao repairOrderDao = RepairOrderDao.getInstance();
	
    private ClaimBillMaintainDAO claimbillmaindao =  ClaimBillMaintainDAO.getInstance();

	private DeCommonDao commonDao = DeCommonDao.getInstance();

	private String itemActivityCode;//维修项目服务活动编号

	private String partActivityCode;//维修配件服务活动编号

	@Override
	protected DEMessage handleExecutor(DEMessage msg) {

		logger.info("====工单上报开始====");
		
		String msgId = msg.getMsgId();
		
		Map<String, Serializable> bodys = msg.getBody();

		for (Entry<String, Serializable> entry : bodys.entrySet()) {

			RepairOrderVO vo = new RepairOrderVO();

			vo = (RepairOrderVO) entry.getValue();

			try {
				
			   POContext.beginTxn(DBService.getInstance().getDefTxnManager(), -1);
			   
			   untieRepairOrderVO(vo);
				
			   /*int i = this.updateDeMsgInfoProcess(msgId);
				
				if(1 == i){
					logger.info("+++++DE_MSG_INFO更新执行状态成功+++++");	
				}else{
					logger.error("-----DE_MSG_INFO更新执行状态失败-----");
				}*/
				
			   POContext.endTxn(true);
			   
			} catch (Exception e) {
				
				POContext.endTxn(false);
				
				logger.error("工单上报失败", e);								
				
			}finally{
				 POContext.cleanTxn();
			}			
		}
		logger.info("====工单上报结束====");

		return null;
	}

	/**
	 * 
	 * @Title: untieRepairOrderVO 
	 * @Description: TODO(将上报的VO存到相应的PO里面) 
	 * @param @param vo
	 * @param @throws Exception    设定文件 
	 * @return void    返回类型 
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	private void untieRepairOrderVO(RepairOrderVO vo) throws Exception {

		/***********维修工单主表PO 新增维修工单主表***********/
		TtAsRepairOrderPO ttAsRepairOrderPO = new TtAsRepairOrderPO();	 
		
		Map<String, Object> map = commonDao.getDcsDealerCode(vo.getEntityCode());

		ttAsRepairOrderPO.setDealerCode(map.get("DEALER_CODE").toString());
		
		Map companyCode = commonDao.getDcsCompanyCode(vo.getEntityCode());
		
		long oemCompanyId = this.getOemCompanyIdByCode(companyCode.get("DCS_CODE").toString());//YH 2010.12.9

		ttAsRepairOrderPO.setDealerId(Long.parseLong(map.get("DEALER_ID").toString())); //YH 2010.11.30

		ttAsRepairOrderPO = assemblePO(ttAsRepairOrderPO, vo);
		
		ttAsRepairOrderPO.setId(Long.parseLong(SequenceManager.getSequence("")));

		ttAsRepairOrderPO.setCreateDate(vo.getDownTimestamp());
		
		if("11441004".equals(ttAsRepairOrderPO.getRepairTypeCode())){ //如果维修类型是保养的 YH 2010.12.09
			Integer freeTimes =  this.updateFreeTimes(ttAsRepairOrderPO.getVin());
			ttAsRepairOrderPO.setFreeTimes(freeTimes);
			if(1 == this.isFree(ttAsRepairOrderPO.getVin(), ttAsRepairOrderPO.getOutMileage(), oemCompanyId)){
				ttAsRepairOrderPO.setApprovalYn(1);
			}else if(0 == this.isFree(ttAsRepairOrderPO.getVin(), ttAsRepairOrderPO.getOutMileage(), oemCompanyId)){
			    ttAsRepairOrderPO.setApprovalYn(0);
			}
		}
		
		if("11441002".equals(ttAsRepairOrderPO.getRepairTypeCode())){ //如果维修类型是外出维修 YH 2010.12.09
			 ttAsRepairOrderPO.setApprovalYn(1); //需要预授权
		}
		
		//ttAsRepairOrderPO.setRoStatus(Constant.RO_STATUS_01);//设为未结算 YH 2010.11.30
		
		ttAsRepairOrderPO.setIfStatus(DEConstant.IF_STATUS_0);//默认为未下发状态				
		
		ttAsRepairOrderPO.setOrderValuableType(Constant.RO_PRO_STATUS_01);

		//把行驶总里程更新到车辆表 如果下端的里程大于车信表的就更新 否则用车信表的里程为工单里程 YH 2010.12.29
		TmVehiclePO vehicle1 = new TmVehiclePO();

		vehicle1.setVin(ttAsRepairOrderPO.getVin());

		TmVehiclePO vehicle2 = new TmVehiclePO();

		vehicle2.setMileage(ttAsRepairOrderPO.getInMileage());

		if (compareInMileage(repairOrderDao, vehicle1, vehicle2)) {//YH 2010.11.30 如果下端的Mileage大于上端的就更新
			repairOrderDao.update(vehicle1, vehicle2);
		}else {			
			List list = repairOrderDao.select(vehicle1);
			if (list.size() > 0) {
				TmVehiclePO tp = (TmVehiclePO) list.get(0);
				ttAsRepairOrderPO.setInMileage(tp.getMileage());
			}
		}
		//更新RoNo
		ttAsRepairOrderPO.setRoNo(this.replaceRO(repairOrderDao,
				ttAsRepairOrderPO.getRepairTypeCode(), ttAsRepairOrderPO
						.getRoNo(), ttAsRepairOrderPO.getDealerCode()));
			
		     repairOrderDao.delCascade(ttAsRepairOrderPO); //先根据DEALER_CODE和RO_NO删除原来的记录
		 				
		//更新车辆表结束

		/***********附加项目PO,新增记录到附加项目表*********/
		LinkedList addItemVoList = vo.getAddItemVoList();

		List<PO> ttAsRoAddItemPOs = new ArrayList<PO>();

		for (int i = 0; i < addItemVoList.size(); i++) {

			TtAsRoAddItemPO ttAsRoAddItemPO = new TtAsRoAddItemPO();

			RoAddItemVO roAddItemVO = (RoAddItemVO) addItemVoList.get(i);

			ttAsRoAddItemPO = assemblePO(ttAsRoAddItemPO, roAddItemVO);

			ttAsRoAddItemPO.setId(Long.parseLong(SequenceManager.getSequence("")));

			ttAsRoAddItemPO.setRoId(ttAsRepairOrderPO.getId());

			ttAsRoAddItemPO.setCreateDate(roAddItemVO.getDownTimestamp());

			ttAsRoAddItemPOs.add(ttAsRoAddItemPO);
		}
		repairOrderDao.insert(ttAsRoAddItemPOs);
		logger.info("Insert TtAsRoAddItemPO success.");

		/******************维修项目PO,新增记录到维修项目表************/
		LinkedList labourVoList = vo.getLabourVoList();

		List<PO> TtAsRoLabourPOs = new ArrayList<PO>();

		for (int i = 0; i < labourVoList.size(); i++) {

			TtAsRoLabourPO ttAsRoLabourPO = new TtAsRoLabourPO();

			RoLabourVO roLabourVO = (RoLabourVO) labourVoList.get(i);

			ttAsRoLabourPO = assemblePO(ttAsRoLabourPO, roLabourVO);

			ttAsRoLabourPO.setId(Long.parseLong(SequenceManager.getSequence("")));

			ttAsRoLabourPO.setRoId(ttAsRepairOrderPO.getId());

			ttAsRoLabourPO.setCreateDate(roLabourVO.getDownTimestamp());

			TtAsRoLabourPOs.add(ttAsRoLabourPO);

			this.itemActivityCode = roLabourVO.getActivityCode();
		}
		repairOrderDao.insert(TtAsRoLabourPOs);
		logger.info("Insert ttAsRoLabourPO success.");

		/******************维修配件PO,新增记录到维修配件表************/
		LinkedList repairPartVoList = vo.getRepairPartVoList();

		List<PO> ttAsRoRepairPartPOs = new ArrayList<PO>();

		for (int i = 0; i < repairPartVoList.size(); i++) {

			TtAsRoRepairPartPO ttAsRoRepairPartPO = new TtAsRoRepairPartPO();

			RoRepairPartVO roRepairPartVO = (RoRepairPartVO) repairPartVoList.get(i);

			ttAsRoRepairPartPO = assemblePO(ttAsRoRepairPartPO, roRepairPartVO);

			ttAsRoRepairPartPO.setId(Long.parseLong(SequenceManager.getSequence("")));

			ttAsRoRepairPartPO.setRoId(ttAsRepairOrderPO.getId());

			ttAsRoRepairPartPO.setCreateDate(roRepairPartVO.getDownTimestamp());
			
			if("S".equals(ttAsRoRepairPartPO.getChargePartitionCode())){
				ttAsRoRepairPartPO.setPayType(Constant.PAY_TYPE_02);
			}

			ttAsRoRepairPartPOs.add(ttAsRoRepairPartPO);

			this.partActivityCode = roRepairPartVO.getActivityCode();
		}
		repairOrderDao.insert(ttAsRoRepairPartPOs);
		logger.info("Insert ttAsRoRepairPartPO success.");

		/******************维修工单辅料管理费PO,新增记录到工单辅料管理费表************/
		LinkedList manageVoList = vo.getManageVoList();

		List<PO> ttAsRoManagePOs = new ArrayList<PO>();

		for (int i = 0; i < manageVoList.size(); i++) {

			TtAsRoManagePO ttAsRoManagePO = new TtAsRoManagePO();

			RoManageVO roManageVO = (RoManageVO) manageVoList.get(i);

			ttAsRoManagePO = assemblePO(ttAsRoManagePO, roManageVO);

			ttAsRoManagePO.setId(Long
					.parseLong(SequenceManager.getSequence("")));

			ttAsRoManagePO.setRoId(ttAsRepairOrderPO.getId());

			ttAsRoManagePO.setCreateDate(roManageVO.getDownTimestamp());

			ttAsRoManagePOs.add(ttAsRoManagePO);
		}
		repairOrderDao.insert(ttAsRoManagePOs);
		logger.info("Insert ttAsRoManagePO success.");
		//最后插入工单表  工单表的服务活动编号赋值
		if (Utility.testString(itemActivityCode)) {

			ttAsRepairOrderPO.setCamCode(itemActivityCode);

		} else {

			ttAsRepairOrderPO.setCamCode(partActivityCode);
		}
		ttAsRepairOrderPO.setRemark2("");
		repairOrderDao.insert(ttAsRepairOrderPO);
		logger.info("Insert ttAsRepairOrderPO success.");
	}

	@SuppressWarnings("unused")
	private int updateDeMsgInfoProcess(String msgId){
		String sql = "UPDATE de_msg_info de SET de.PROCESS = ? WHERE de.msg_id = ? ";
		List param = new ArrayList(); //更新数据
		param.add(1);
		param.add(msgId);		
		int i = repairOrderDao.update(sql, param);
		return i;
	}
	
	private <T extends PO> T assemblePO(T po, BaseVO vo) throws Exception {

		BeanUtils.copyProperties(po, vo);

		return po;
	}

	@SuppressWarnings( { "unused", "unchecked" })
	//比较行政里程比车辆表大的就更新 YH 2010.11.30
	private boolean compareInMileage(RepairOrderDao dao, TmVehiclePO tp1,
			TmVehiclePO tp2) {

		List list = dao.select(tp1);

		boolean b = false;

		if (list.size() > 0) {

			TmVehiclePO tp = (TmVehiclePO) list.get(0);

			if (tp.getMileage() < tp2.getMileage()) {

				b = true;
			}

		}
		return b;
	}

	//替换工单号RO为类型标识  YH.2010.12.9
	@SuppressWarnings( { "unused", "unchecked" })
	private String replaceRO(RepairOrderDao repairOrderDao,
			String repairTypeCode, String roNo, String dealerCode) {

		String sql = " select BILL_TYPE from TM_BILL_TYPE where REPAIR_TYPE_CODE = '"
				+ repairTypeCode + "' ";

		Map<String, Object> map = repairOrderDao.pageQueryMap(sql, null,
				repairOrderDao.getFunName());

		String BILL_TYPE = map.get("BILL_TYPE").toString();

		String newRoNo = dealerCode + roNo.replace("RO", BILL_TYPE);

		return newRoNo;
	}
	
	
	@SuppressWarnings("unchecked")
	public Integer updateFreeTimes(String vin){
		
		TmVehiclePO tvp = new TmVehiclePO();		
		tvp.setVin(vin);
		List list =  commonDao.select(tvp);		
		if(list.size()>0){
			tvp = (TmVehiclePO)list.get(0);	
		}
		Integer freeTimes  = tvp.getFreeTimes();
		if("".equals(freeTimes)|| null == freeTimes){
			freeTimes = 1;
		}else{
			freeTimes = freeTimes+1;
		}
		return freeTimes;
	}
	
	@SuppressWarnings("unchecked") //通过companyCode得到oemcompanyId YH.2010.12.09
	public long getOemCompanyIdByCode(String companyCode){
		
	  TmCompanyPO tc = 	new TmCompanyPO();
	  
	  tc.setCompanyCode(companyCode);
	  
	  List list =  commonDao.select(tc);
	  
	  if(list.size()>0){	  
		  tc  = (TmCompanyPO)list.get(0);	  
	  }
	  
	  return tc.getOemCompanyId();
	}
	

	  //判断是否脱保 是否需要预授权
	@SuppressWarnings("unchecked")
	public Integer isFree(String vin,Double mileage,long companyId){
		int allTimes = 0;
		Date date = new Date();
		int day = 999999;
		int month = 999999; //当前时间和保修开始时间相差月份
		TmVehiclePO tvp = new TmVehiclePO();
		tvp.setVin(vin);
		List<TmVehiclePO> lsv = claimbillmaindao.select(tvp);
		if (lsv!=null) {
			if (lsv.size()>0) {
				tvp = lsv.get(0);
				date = tvp.getPurchasedDate(); //保修改开始时间
			}
		}
		Date now = new Date(); //今天
		if (date!=null) {
			String formatStyle ="yyyy-MM-dd";  
			SimpleDateFormat df = new SimpleDateFormat(formatStyle);  
			String d1 = df.format(date);
			String d2 = df.format(now);
			month  = Utility.compareDate(d1,d2,1); //取得今日和保养开始时间的差值
			day = Utility.compareDate(d1, d2, 0); //取得今日和保养开始时间的差值 天数
		}
		List<Map<String, Object>> freeTimes = claimbillmaindao.viewFreeTime1(vin);
		//判断保养次数是否为空
		if(freeTimes.get(0).get("FREE_TIMES")==null||freeTimes.get(0).get("FREE_TIMES").equals("")){
			allTimes=0;
		}
		else{allTimes = Integer.valueOf(freeTimes.get(0).get("FREE_TIMES").toString());}
		List<TtAsWrQamaintainPO> lsq=null;
		lsq =  claimbillmaindao.getFree(allTimes+1,companyId,month,day,Double.valueOf(mileage));
		if (lsq!=null) { //存在记录，不需要授权
			if (lsq.size()>0) {
			    return Constant.APPROVAL_YN_NO;
			}else {
			    return Constant.APPROVAL_YN_YES;
			}
		}else {
			return Constant.APPROVAL_YN_NO;
		}
	}
	/*public static void main(String[] args) {
	 ContextUtil.loadConf();
	 POContext.beginTxn(DBService.getInstance().getDefTxnManager(), -1);
	 ORC53 o = new ORC53();
	 try {
		 File file = new File("c:/20101129141448859000002875.dat");
		 InputStream is = new FileInputStream(file);
		 byte[] b = new byte[is.available()];
		 is.read(b, 0, b.length);
		 XmlConvertor4YiQiP01 xml = new XmlConvertor4YiQiP01();
		 DEMessage msg = xml.convert(b);
		 System.out.println(msg.getAppName());
		 Map<String, Serializable> bodys = msg.getBody();
		 is.close();
		 o.handleExecutor(msg);
		 POContext.endTxn(true);
	 } catch (Exception e) {
		 	POContext.endTxn(false);
	        e.printStackTrace();
	     } finally{
	    	 POContext.cleanTxn();
	   }
    }*/
}

